import assert from 'assert';
import path from 'path';
import { lodash, winPath } from '@fesjs/utils';

const reserveLibrarys = ['fes']; // reserve library
// todo 插件导出内容冲突问题待解决
const reserveExportsNames = ['Link', 'NavLink', 'Redirect', 'dynamic', 'withRouter', 'Route'];

export default function generateExports(basePath, { item, fesExportsHook }) {
    assert(item.source, 'source should be supplied.');
    const source = path.relative(path.basename(basePath), item.source);
    assert(item.exportAll || item.specifiers, 'exportAll or specifiers should be supplied.');
    assert(!reserveLibrarys.includes(source), `${source} is reserve library, Please don't use it.`);
    if (item.exportAll) {
        return `export * from '${winPath(source)}';`;
    }
    assert(Array.isArray(item.specifiers), `specifiers should be Array, but got ${item.specifiers.toString()}.`);
    const specifiersStrArr = item.specifiers.map((specifier) => {
        if (typeof specifier === 'string') {
            assert(!reserveExportsNames.includes(specifier), `${specifier} is reserve name, you can use 'exported' to set alias.`);
            assert(!fesExportsHook[specifier], `${specifier} is Defined, you can use 'exported' to set alias.`);
            fesExportsHook[specifier] = true;
            return specifier;
        }
        assert(lodash.isPlainObject(specifier), `Configure item context should be Plain Object, but got ${specifier}.`);
        assert(specifier.local && specifier.exported, 'local and exported should be supplied.');
        return `${specifier.local} as ${specifier.exported}`;
    });
    return `export { ${specifiersStrArr.join(', ')} } from '${winPath(source)}';`;
}
